package com.spic.business.alarm.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spic.business.alarm.domain.DeviceInfoVo;
import com.spic.business.alarm.domain.FangPiLaoAlarmModel;
import com.spic.business.alarm.domain.FloodAlarm;
import com.spic.business.alarm.domain.WeatherDataModel;
import com.spic.business.alarm.mapper.FangPiLaoAlarmMapper;
import com.spic.business.alarm.mapper.WeatherDataMapper;
import com.spic.business.alarm.service.DeviceService;
import com.spic.business.alarm.service.IAlarmDataService;
import com.spic.business.config.TemplateConfig;
import com.spic.business.enumconst.BusinessType;
import com.spic.business.violation.supervision.action.domain.ViolationActionInput;
import com.spic.business.violation.supervision.information.domain.ViolationInformation;
import com.spic.common.core.utils.DateUtils;
import com.spic.common.core.utils.StringUtils;
import com.spic.system.api.RemoteDictDataService;
import com.spic.system.api.RemoteStatus;
import com.spic.system.api.domain.BusinessStatus;
import com.spic.system.api.domain.SysDictData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AlarmDataServiceImpl  extends ServiceImpl<FangPiLaoAlarmMapper, FangPiLaoAlarmModel>
        implements IAlarmDataService {

    @Autowired
    private WeatherDataMapper weatherDataMapper;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private RemoteDictDataService remoteDictDataService;
    @Autowired
    private RemoteStatus remoteStatus;
    @Autowired
    private TemplateConfig templateConfig;
    /**
     * 防疲劳告警信息查询
     * @param type
     * @return
     */
    @Override
    public JSONObject getAlarmList(String type,String date) {
        JSONObject json = new JSONObject();
        if("1".equals(templateConfig.getYingJian())) {
            List<Map<String,Object>> totleList = new ArrayList<>();
            if("day".equals(date)){
                totleList.add(this.createTotleMap("phone", 0));
                totleList.add(this.createTotleMap("smoking", 0));
                totleList.add(this.createTotleMap("distracted", 0));
                totleList.add(this.createTotleMap("abnormal", 2));
            }else{
                totleList.add(this.createTotleMap("phone", 0));
                totleList.add(this.createTotleMap("smoking", 0));
                totleList.add(this.createTotleMap("distracted", 4));
                totleList.add(this.createTotleMap("abnormal", 5));
            }
            json.put("warmtypenum",totleList);
            JSONObject obj = new JSONObject();
            obj.put("atp", "phone");
            obj.put("did", "018006804170");
            obj.put("etm", "2022-09-20 14:05:37");
            obj.put("ssp", "18.0");
            obj.put("stm", "2022-09-20 14:05:37");
            obj.put("vid", "电80");
            JSONArray arr = new JSONArray();
            arr.add(obj);
            json.put("warmlist", arr);
        } else {
            List<FangPiLaoAlarmModel> list =new ArrayList<>();
            String monthDate;
            if("day".equals(date)){
                list = this.baseMapper.selectAlarmList(String.valueOf(DateUtils.getZeroTimestamp()));
            }else{
                Date parse = null;
                Date parseEnd = null;
                try
                {
                    //当月第一天时间戳
                    parse = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(DateUtils.initDateByMonth());
                    Long timestart = parse.getTime();

                    //当月最后一天时间戳

                    parseEnd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(DateUtils.initEndDateByMonth());
                    Long timeEnd = parseEnd.getTime();
                    list = this.baseMapper.selectAlarmListMonth(String.valueOf(timestart),String.valueOf(timeEnd));
                } catch (ParseException e)
                {
                    e.printStackTrace();
                }
            }


            Map<String,String> typeMap = new HashMap<>();
            typeMap.put("620", "phone");//接打电话
            typeMap.put("621", "phone");
            typeMap.put("622", "smoking");//抽烟
            typeMap.put("623", "smoking");
            typeMap.put("624", "distracted");//分神
            typeMap.put("625", "distracted");
            typeMap.put("626", "abnormal");//驾驶员异常
            typeMap.put("627", "abnormal");

            list.stream().map(item -> {
                item.setAtp(typeMap.get(item.getAtp()));
                if(item.getStm()!=null){
                    item.setStm(DateUtils.timestampToDateStr(item.getStm()));
                }
                if(item.getEtm()!=null){
                    item.setEtm(DateUtils.timestampToDateStr(item.getEtm()));
                }
                return item;
            }).collect(Collectors.toList());
            //拆分数据列表
            List<FangPiLaoAlarmModel> list1 = this.filterListData(list,"phone");
            List<FangPiLaoAlarmModel> list2 = this.filterListData(list,"smoking");
            List<FangPiLaoAlarmModel> list3 = this.filterListData(list,"distracted");
            List<FangPiLaoAlarmModel> list4 = this.filterListData(list,"abnormal");
            //分装数据汇总条数
            List<Map<String,Object>> totleList = new ArrayList<>();
            totleList.add(this.createTotleMap("phone", list1.size()));
            totleList.add(this.createTotleMap("smoking", list2.size()));
            totleList.add(this.createTotleMap("distracted", list3.size()));
            totleList.add(this.createTotleMap("abnormal", list4.size()));
            json.put("warmtypenum",totleList);
            //按类型查找数据列表
            if(StringUtils.isNotEmpty(type)){
                switch (type) {
                    case "phone":
                        json.put("warmlist", list1);
                        break;
                    case "smoking":
                        json.put("warmlist", list2);
                        break;
                    case "distracted":
                        json.put("warmlist", list3);
                        break;
                    case "abnormal":
                        json.put("warmlist", list4);
                        break;
                }
            }else{
                json.put("warmlist",list);
            }
        }
        return json;
    }

    /**
     * 防汛告警信息查询
     * @return
     */
    @Override
    public JSONObject getFloodAlarm() {
        JSONObject json = new JSONObject();
        WeatherDataModel weatherDataModel = weatherDataMapper.getNewestOne();
        json.put("rainVolum",weatherDataModel.getRainVolum());//当前雨量
        List<FloodAlarm> list = this.baseMapper.selectFloodAlarmList(DateUtils.getZeroDateTime());
        for(FloodAlarm fa : list){
            DeviceInfoVo deviceInfoVo = deviceService.getDeviceByDeviceName(fa.getDevice());
            fa.setLatitude(String.valueOf(deviceInfoVo.getLatitude()));
            fa.setLongitude(String.valueOf(deviceInfoVo.getLongitude()));
            fa.setAlarmContent(deviceInfoVo.getDeviceType());
        }
        json.put("alarmList",list);//告警设备
        return json;
    }

    /**
     * 违章举报查询-当月已办理完毕数据
     * @param type 分类
     * @param date day=当天数据，month=当月数据 year=当年数据
     * @return 返回的数据
     */
    @Override
    public JSONObject getInformationList(String type, String date) {
        JSONObject json = new JSONObject();
        String monthDate ="";
        if("day".equals(date)){
            monthDate = DateUtils.getZeroDateTime();
        }else if ("month".equals(date)){
            monthDate = DateUtils.initDateByMonth();
        }else if("year".equals(date)){
            monthDate = DateUtils.initDateByYear();
        }

        //数据总列表
        List<ViolationInformation> voList = this.baseMapper.selectViolationInformationListFromIoc02(monthDate);
        //违章分类字段数据列表
        List<SysDictData> dictList = remoteDictDataService.getDictDataByDictType("violations_classification").getData();
        //数据分类汇总数据列表
        List<Map<String,Object>> totleList = new ArrayList<>();
        List<ViolationInformation> dataList = new ArrayList<>();
        //未处理的数据
        int dealNum = 0;
        if (voList != null && voList.size() > 0){
            //全部数据id列表
            List<String> keys  = voList.stream().map(item -> String.valueOf(item.getId())).collect(Collectors.toList());
            //全部数据流程状态列表
            List<BusinessStatus> statusList =  remoteStatus.getStateBybusinessIds(BusinessType.VIOLATION_INFORMATION.getBusinessType(), keys).getData();
            if(statusList != null && statusList.size() > 0) {
                //已提交数据状态列表 -状态为2/3
                List<String> processedList = statusList.stream().filter(item -> item.getStatus() == 3 || item.getStatus() == 2)
                        .map(BusinessStatus::getBusinessKey).collect(Collectors.toList());
                //已提交的流程数据列表
                dataList = voList.stream().filter(item -> processedList.contains(item.getId().toString())).collect(Collectors.toList());
                //处理中的数据pid列表 -状态为2
                List<String> dealPidList = statusList.stream().filter(item -> item.getStatus() == 2)
                        .map(BusinessStatus::getProcessInstanceId).collect(Collectors.toList());
                //处理中数据流程当前办理节点信息列表
                List<String> dealKeyList =  remoteStatus.getTaskInfoList(dealPidList).getData();
                //未处理的流程数据
                if(dealKeyList != null) {
                    dealNum = (int) dealKeyList.stream().filter("dept_process"::equals).count();
                }
            }
        }
        json.put("remark",this.createRemark(dealNum, dataList.size()));
        for(SysDictData dict : dictList){
            //分类列表数据
            List<ViolationInformation> typeList = this.filterViolationInformationListData02(dataList,dict.getDictValue());
            totleList.add(this.createTotleMap(dict.getDictValue(), typeList.size()));
            if(StringUtils.isNotEmpty(type) && type.equals(dict.getDictValue())){
                json.put("warmlist", typeList);
            }
        }
        json.put("warmtypenum",totleList);
        if(StringUtils.isEmpty(type)){
            json.put("warmlist", dataList);
        }
        return json;
    }

    /**
     * 获取隐患排查数据
     * @date week=7天内数据，year=当年数据
     * @return
     */
    @Override
    public JSONObject getHiddenList(String date) {
        JSONObject json = new JSONObject();
        String monthDate;
        String time;
        if("week".equals(date)){
            monthDate = DateUtils.getDateTimeBefore("7");
            time="近一周";
        }else{
            monthDate = DateUtils.initDateByYear();
            time="本年度";
        }
        List<String> list = this.baseMapper.getHiddenList(monthDate);
        //已完成
        List<String> dealList = list.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
        if(list.size()>0){

            json.put("remark",time+"隐患已排查:"+list.size()+",已整改:"+dealList.size()+",隐患排查整改达标率 "+
                    this.calculatePercentage(new BigDecimal(dealList.size()),new BigDecimal(list.size()))+"%");
        }
        return json;
    }

    /**
     * 通过某字段值拆分数据列表
     * @param list 数据列表
     * @param type 字段类型
     * @return 拆分后的列表
     */
    public List<ViolationActionInput> filterViolationInformationListData(List<ViolationActionInput> list,String type){
        return list.stream().filter(f -> f.getIllegalClassify().equals(type)).collect(Collectors.toList());
    }

    /**
     * 通过某字段值拆分数据列表
     * @param list 数据列表
     * @param type 字段类型
     * @return 拆分后的列表
     */
    public List<ViolationInformation> filterViolationInformationListData02(List<ViolationInformation> list,String type){
        List<ViolationInformation> list1 =  list.stream().filter(f -> f.getViolationsClassification().equals(type)).collect(Collectors.toList());
        return list1;
    }

    /**
     * 通过某字段值拆分数据列表
     * @param list 数据列表
     * @param type 字段类型
     * @return 拆分后的列表
     */
    public List<FangPiLaoAlarmModel> filterListData(List<FangPiLaoAlarmModel> list,String type){
        return list.stream().filter(f -> f.getAtp().equals(type) ).collect(Collectors.toList());
    }

    /**
     * 封装汇总条数-共用
     * @param type 类型字段
     * @param totle 类型列表数据条数
     * @return map
     */
    public Map<String,Object> createTotleMap(String type, int totle){
        Map<String,Object> totleMap = new HashMap<>();
        totleMap.put("typename",type);
        totleMap.put("typenum",totle);
        return totleMap;
    }

    /**
     * 计算百分比-保留两位小数
      * @param divisor 除数
     * @param dividend 被除数
     * @return 百分比
     */
    public BigDecimal calculatePercentage(BigDecimal divisor, BigDecimal dividend){
        return divisor.multiply(new BigDecimal(100)).
                divide(dividend, 2, BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 拼接remark
     * @param deal 未受理数
     * @param count 流程提交数
     * @return remark
     */
    public String createRemark(int deal, int count){
        if(count==0){
            return "违章举报: 0条 受理: 0条  受理率: 0%";
        }else{
            //已受理数
            int process = count - deal;
            return "违章举报: "+count+"条 受理: "+process+"条  受理率: "+
                    this.calculatePercentage(new BigDecimal(process), new BigDecimal(count))+"%";
        }
    }

}
